package mx.com.crowdgine.game;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;

import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.glu.gl2.GLUgl2;

import mx.com.crowdgine.util.ResourceFinder.*;
import mx.com.crowdgine.app.JoglApplication;
import mx.com.crowdgine.assetloader.Asset;
import mx.com.crowdgine.assetloader.OBJModelAsset;
import mx.com.crowdgine.camera.JoglCamera;
import mx.com.crowdgine.display.animation.glsl.GLSLAnimation;
import mx.com.crowdgine.assetloader.*;
import mx.com.crowdgine.assetloader.audio.AudioManager;

import com.jme3.input.MouseInput;
import com.jogamp.common.nio.Buffers;



public class EngineDemo extends JoglApplication{
	private int crowdSize = 3*3;
	AudioManager bgMusic;
	AudioManager explosionEffect;
	
	private FloatBuffer dataArray []= new FloatBuffer[crowdSize];
	private FloatBuffer light;
	public Asset crowds[] = new Asset[crowdSize];
		
	public EngineDemo(String frameName, int width, int height){
		super(frameName, width, height);
	}
	
	public static void main(String [] args){
		EngineDemo crowdGame =  new EngineDemo("Enter The Penguin. . . Clash at The stadium!!! Naruto to the rescue!" , 640, 480);
		crowdGame.start();
	}
	
	public void initialize(){
		super.initialize();
		addAndSetCamera(new JoglCamera());
	    
	    for(int i = 0; i < crowdSize ; i ++){
	    	crowds[i] = new OBJModelAsset();
	    	crowds[i].setAnimation(new GLSLAnimation("Assets/shaders/textureVertex.glsl", "Assets/shaders/textureFragment.glsl"));
	    	if(i < 3)
	    	crowds[i].setAssetName("Assets/Models/mrT");
	    	else if(i < 7)
	    		crowds[i].setAssetName("Assets/Models/jack");
	    	else if(i < 12)
	    		crowds[i].setAssetName("Assets/Models/jack");
	    	
	    	addAsset(crowds[i]);
	    }
	}
	
	public void initCrowdPositionData(){
		float posX = -10;
		float posY =  0;
		float posZ =  10;
		float stride = 10;
		float value[] = new float[]{0f,0.0f, 0.0f, 0.0f};
		
		double length = Math.pow(crowdSize, 0.5);
		
		for(int i = 0; i < length ; i++){
			for(int j = 0; j <length; j++){
				dataArray[(int)(j+(i*length))] = Buffers.newDirectFloatBuffer(value);
				dataArray[(int)(j+(i*length))].put(0,posX + (stride *j));
				dataArray[(int)(j+(i*length))].put(1,posY);
				dataArray[(int)(j+(i*length))].put(2,posZ + (stride *i));
			}
			
		}	
	}
	
	
	public void init(GLAutoDrawable drawable){
		super.init(drawable);
		initCrowdPositionData();
		System.out.println("Init drawable in Variety Playground");
		GL2 gl = drawable.getGL().getGL2();
		bgMusic = new AudioManager("Assets/Audio/backpower.mid");
		
		
		explosionEffect = new AudioManager("Assets/Audio/die.wav");

		glTexture = allocateTextureBuffer(256, 256, 4);  // Get An Image Structure
        try {
            // Fill The Image Structure With Data
            readTextureData("Assets/Textures/monitor.raw", glTexture);  
        } catch (IOException e) {                               // Nothing Read?
            System.out.println("Could not read Assets/Textures/texture.raw");
            throw new RuntimeException(e);
        }
        
        glTexture2 = allocateTextureBuffer(256, 256, 4);  // Get An Image Structure
        try {
            // Fill The Image Structure With Data
            readTextureData("Assets/Textures/monitor.raw", glTexture2);  
        } catch (IOException e) {                               // Nothing Read?
            System.out.println("Could not read Assets/Textures/monitor.raw");
            throw new RuntimeException(e);
        }
        
		
		buildTexture(gl, glu, glTexture);    // Load The Texture Map Into Texture Memory
		//buildTexture(gl, glu, glTexture2); 
	        
		gl.glEnable(GL.GL_TEXTURE_2D);
		bgMusic.play();
	}
	
	public void initInput(){
		super.initInput();
		addMouseButtonMapping("LeftClick", MouseInput.BUTTON_LEFT);
		addMouseButtonMapping("RightClick", MouseInput.BUTTON_RIGHT);
	}
	
	
	public void update(GLAutoDrawable drawable){
		super.update(drawable);
		inputManager.update();

		float light[] = new float[]{1.0f,1.0f,1.0f};
		
		FloatBuffer lightData = Buffers.newDirectFloatBuffer(light);
		
		crowds[0].getAnimation().setParameter("color_texture" , glTexture);
		
		crowds[1].getAnimation().setParameter("color_texture" , glTexture);
		crowds[1].getAnimation().setParameter("LightPos0", new float[]{1.0f,1.0f,1.0f});
		
		for(int i = 0; i<crowdSize; i++){
		
			crowds[i].getAnimation().setParameter("roll" , time);
			crowds[i].getAnimation().setParameter("LightPos0", lightData, 4, 4);
			crowds[i].getAnimation().setParameter("position", dataArray[i], 4, 4);
			
		}
		
		time+=0.1;
	}
	
	@Override
	protected void updateActionListener(String name, boolean pressed){
		super.updateActionListener(name, pressed);
		if(name=="LeftClick" && pressed){
			System.out.println("ROFL");
			explosionEffect.play();
		}
		if(name=="RightClick" && pressed){
			System.out.println("LMAO TSE TUNG");
			explosionEffect.stop();
		}
	}
	
	@Override
	protected void updateAnalogListener(String name, float value){
		super.updateAnalogListener(name, value);
		//if(name=="MouseLeft"){
		//	System.out.println("Left! value: "+value);
		//}
	}
	
	///////////////////////////////////////Cambiar para que se haga en el renderer
	
	private int textures[] = new int[1];    // Storage For 6 Textures (Modified)
	
	TextureImage glTexture;
	TextureImage glTexture2;

	private GLUgl2 glu = new GLUgl2();
	
	private class TextureImage {
	    int width;          // Width Of Image In Pixels
	    int height;          // Height Of Image In Pixels
	    int format;          // Number Of Bytes Per Pixel
	    ByteBuffer data;        // Texture Data
	}
	
	public float time;
	
	 private TextureImage allocateTextureBuffer(int w, int h, int f) {
	        TextureImage ti = new TextureImage();     // Pointer To Image Struct
	        ti.width = w;          // Set Width
	        ti.height = h;          // Set Height
	        ti.format = f;          // Set Format
	       // ti.data = ByteBuffer.allocateDirect(w * h * f);
	        ti.data = ByteBuffer.allocate(w * h * f);
	       ti.data.position(0);
	        ti.data.limit(ti.data.capacity());
	        return ti;      // Return Pointer To Image Struct
	    }
	
	private void readTextureData(String filename, TextureImage buffer) throws IOException {
    	System.out.println("Reading Texture...");
        int i,j,k,done = 0;
        
        // Size Of A Row (Width * Bytes Per Pixel)
        int stride = buffer.width * buffer.format;

        InputStream inputStream = ResourceRetriever.getResourceAsStream(filename);

        // Loop Through Height (Bottoms Up - Flip Image)
        for (i = buffer.height - 1; i >= 0; i--) { 
            int p = i * stride;          
            for (j = 0; j < buffer.width; j++) {  // Loop Through Width
                for (k = 0; k < buffer.format - 1; k++, p++, done++) {
                	byte inputRead = (byte) inputStream.read();
                	//System.out.println("inserting color "+p+": "+inputRead);
            		// Read Value From File And Store In Memory
                    buffer.data.put(p, inputRead);  
                }
                //System.out.println("inserting alpha "+p+": "+(byte) 255);
                buffer.data.put(p, (byte) 255);
                p++;  // Store 255 In Alpha Channel And Increase Pointer
            }
        }
        inputStream.close();      // Close The File
    }
	
	
	 private void buildTexture(GL gl, GLUgl2 glu, TextureImage tex) {
	    	System.out.println("Building Texture...");
	        gl.glGenTextures(1, textures, 0);
	        gl.glBindTexture(GL.GL_TEXTURE_2D, textures[0]);
	        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
	        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
	        glu.gluBuild2DMipmaps(GL.GL_TEXTURE_2D, GL.GL_RGB, tex.width, tex.height, 
	               GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, tex.data);
	    }
	
	
	
	
	
	
	/////////////////////////////////////////fin de la basura
	
}
